package Leetcode.StackAndQueue.MyCircularDeque641;

public class Solution {
    /**
     * Initialize your data structure here. Set the size of the deque to be k.
     */
    private int k;
    private int size;
    private Node head;
    private Node tail;

    public Solution(int k) {
        this.k = k;
        this.size = 0;
        tail = head;
    }

    /**
     * Adds an item at the front of Deque. Return true if the operation is successful.
     */
    public boolean insertFront(int value) {
        if(size == k) {
            return false;
        }
        if(size == 0) {
            Node node = new Node(value);
            head = node;
            tail = node;
            size++;
            return true;
        }
        Node node = new Node(value);
        node.next = head;
        head = node;
        size++;
        return true;
    }

    /**
     * Adds an item at the rear of Deque. Return true if the operation is successful.
     */
    public boolean insertLast(int value) {
        if(size == k) {
            return false;
        }
        if(size == 0) {
            Node node = new Node(value);
            head = node;
            tail = node;
            size++;
            return true;
        }
        Node node = new Node(value);
        tail.next = node;
        tail = tail.next;
        size++;
        return true;
    }

    /**
     * Deletes an item from the front of Deque. Return true if the operation is successful.
     */
    public boolean deleteFront() {
        if(size == 0) {
            return false;
        }
        Node node = head.next;
        head.next = null;
        head = null;
        head = node;
        size--;
        return true;
    }

    /**
     * Deletes an item from the rear of Deque. Return true if the operation is successful.
     */
    public boolean deleteLast() {
        if(size == 0) {
            return false;
        }
        if(size == 1) {
            head = null;
            tail = null;
            size = 0;
            return true;
        }
        Node node = head;
        while(!node.next.equals(tail)) {
            node = node.next;
        }
        node.next = null;
        tail = node;
        size--;
        return true;
    }

    /**
     * Get the front item from the deque.
     */
    public int getFront() {
        if(size == 0) {
            return -1;
        }
        return head.value;
    }

    /**
     * Get the last item from the deque.
     */
    public int getRear() {
        if(size == 0) {
            return -1;
        }
        return tail.value;
    }

    /**
     * Checks whether the circular deque is empty or not.
     */
    public boolean isEmpty() {
        return size == 0;
    }

    /**
     * Checks whether the circular deque is full or not.
     */
    public boolean isFull() {
        return size == k;
    }

    class Node {
        int value;
        Node next;


        public Node(int x) {
            this.value = x;
        }
    }

    @Override
    public String toString() {
        StringBuffer stringBuffer = new StringBuffer();
        Node result = head;
        while(result != null) {
            stringBuffer.append(result.value + "-->");
            result = result.next;
        }
        stringBuffer.append("NULL");
        return stringBuffer.toString();
    }

    public static void main(String[] args) {
        Solution solution = new Solution(4);
        solution.insertFront(9);
        System.out.println(solution);
        solution.deleteLast();
        System.out.println(solution);
        System.out.println(solution.getRear());
    }
}
